package com.xframe.xdal.core.model.sqlbuilder.proc;

import com.xframe.xdal.core.constant.DalConstants;
import com.xframe.xdal.core.handler.HandlerColumnMapManage;
import com.xframe.xdal.core.model.mapping.IRelation;
import com.xframe.xdal.core.model.mapping.ITableInfo;
import com.xframe.xdal.core.model.sqlbuilder.BaseSqlBuilder;
import com.xframe.xdal.core.model.sqlbuilder.BuilderContext;
import com.xframe.xdal.core.model.sqlbuilder.SqlExpression;
import lombok.extern.log4j.Log4j2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 功能描述:SELCET主键 返回一个对象
 *
 * @author xufeng
 * @version 1.0
 * @date 2022-09-26
 */
@Log4j2
public class SearchByKeySqlBuilder extends BaseSqlBuilder {

    public String getSQL() {
        return "SELECT %s FROM %s WHERE %s";
    }

    private String colPlaceholder = "`";

    @Override
    public SqlExpression build(BuilderContext context) {
        colPlaceholder = context.getColPlaceholder();
        StringBuilder colstrBuilder = new StringBuilder();
        StringBuilder fromBuilder = new StringBuilder();
        StringBuilder whereBuilder = new StringBuilder();
        List<Object> pList = new ArrayList<>();
        // SQL语音列名称和属性映射对象的位置关系列表  
        HandlerColumnMapManage handlerColumnMapManage = new HandlerColumnMapManage(context.getDataSourceTypeEnums());
        // 处理主表 列名称
        buildMainSelect(context,colstrBuilder,colPlaceholder,context.getTableInfo(),handlerColumnMapManage);
        fromBuilder.append(buildFrom(context,colPlaceholder,context.getTableInfo()));

        Map<String, ITableInfo> refTable = new HashMap<>();
        // 处理引用列
        if(context.getTableInfo().getBelongsToMappingList() != null) {
            for (IRelation belongsToMapping : context.getTableInfo().getBelongsToMappingList()) {
                if (context.includeBelongRefName(belongsToMapping.getAs())) {
                    // 处理from列
                    ITableInfo tableInfo = belongsToMapping.getTableInfoByType();
                    if (tableInfo == null) {
                        continue;
                    }
                    refTable.put(belongsToMapping.getAs(), tableInfo);
                    colstrBuilder.append(DalConstants.SQL_SEPARATION);
                    // 处理Select 子句
                    buildSelect(context, colstrBuilder, belongsToMapping, tableInfo, handlerColumnMapManage,
                            true, false, null);
                    // 构造from子句
                    fromBuilder.append(buildFromJoinFrom(context, colPlaceholder, context.getTableInfo(), tableInfo, belongsToMapping));
                }
            }
        }
        // 处理列表列
        if(context.getTableInfo().getHasManyMappingList() != null) {
            for (IRelation hasManyMapping : context.getTableInfo().getHasManyMappingList()) {
                if (context.includeHasmanyRefName(hasManyMapping.getAs())) {
                    // 处理from列
                    ITableInfo tableInfo = hasManyMapping.getTableInfoByType();
                    if (tableInfo == null) {
                        continue;
                    }
                    refTable.put(hasManyMapping.getAs(), tableInfo);
                    colstrBuilder.append(DalConstants.SQL_SEPARATION);
                    // 处理Select 子句
                    buildSelect(context, colstrBuilder, hasManyMapping, tableInfo,
                            handlerColumnMapManage, false, true, hasManyMapping.getDataType());
                    // 构造from子句
                    fromBuilder.append(buildFromJoinFrom(context, colPlaceholder, context.getTableInfo(), tableInfo, hasManyMapping));
                }
            }
        }
        // 处理查询条件
        context.getConditionValueCollection().builderWhereByKey(context,context.getTableInfo(),colPlaceholder,whereBuilder,pList);
        String sql = String.format(getSQL(), colstrBuilder, fromBuilder, whereBuilder);
        return new SqlExpression(sql, "", pList,handlerColumnMapManage,context.getDataSourceTypeEnums());
    }
}
